package values.inventory
{
import flash.errors.IllegalOperationError;

import utils.VectorUtil;

import values.item.IItemValue;
import values.item.INumbericItemValue;
import values.item.ItemValue;

/**
 * GroupedNumbericItemInventoryValue
 * @author jliang
 *
 */
public class GroupedNumbericItemInventoryValue extends NumbericItemInventoryValue
{
	//==========================================================================
	//  Constructor
	//==========================================================================
	public function GroupedNumbericItemInventoryValue()
	{
		super();
	}
	//==========================================================================
	//  Overridden methods: NumbericItemInventoryValue
	//==========================================================================
	override public function addItem(value:IItemValue):*
	{
		var target:INumbericItemValue = value as INumbericItemValue;
		
		var resultList:Vector.<INumbericItemValue> = new Vector.<INumbericItemValue>();
		
		var matchItem:INumbericItemValue = findItem(value.key);
		
		if (!matchItem && isFull)
		{
			dispatchAddItemFailEvent(target);
			
			return null;
		}
		
		var overNum:Number = 0;
		
		//如果有还未叠满的物品		
		if (matchItem)
		{
			overNum = Math.ceil(matchItem.num + target.num) - matchItem.groupCount;
		}
		//如果没有未叠满的物品 或者 没有目前还没有物品		
		else
		{
			overNum = target.num;
		}
		
		if (matchItem && overNum < 0)
		{
			matchItem.concat(target);
			resultList.push(matchItem);
		}
		else
		{
			var addCount:int = Math.ceil(overNum / target.groupCount);
			
			if ((items.length + addCount) > currentSpace)
			{
				dispatchAddItemFailEvent(target);
				
				return null;
			}
			else
			{
				if (matchItem)
				{
					matchItem.num = matchItem.groupCount;
				}
				
				for (var i:int = 0; i < addCount; i++)
				{
					var newVO:INumbericItemValue = target.clone();
					newVO.num = Math.min(overNum, newVO.groupCount);
					items.push(newVO);
					
					overNum -= newVO.num;
					
					resultList.push(newVO);
				}
			}
		}
		
		if (isFull)
		{
			dispatchFullEvent();
		}
		return resultList.length > 0 ? resultList : null;
	}
	
	override public function removeItem(value:IItemValue):*
	{
		var removed:Vector.<IItemValue> = new Vector.<IItemValue>();
		var target:INumbericItemValue = value as INumbericItemValue;
		var matchItem:INumbericItemValue;		
		var matchs:Vector.<INumbericItemValue> = new Vector.<INumbericItemValue>();
		
		for each (var vo:INumbericItemValue in items)
		{
			if (vo.key == value.key) 
			{
				matchs.push(matchItem);
				if (!vo.isFull)
				{
					matchItem = vo;
					break;
				}
			}
		}
		
		if (!matchItem)
		{
			if (matchs.length == 0) 
			{
				throw new IllegalOperationError("There is no <" + value.key + "> item in the inventory.");
				return;
			}
			
			matchItem = matchs[matchs.length - 1];
		}
		
		var copy:INumbericItemValue = target.clone();
		copy.num = -copy.num;
		
		matchItem.concat(copy);
		
		var loop:Function = function(temp:INumbericItemValue, list:Vector.<IItemValue>, removedList:Vector.<IItemValue>):void
		{
			if (temp.num <= 0)
			{
				VectorUtil.removeObject(temp, list);
				removedList.push(temp);
				
				for each (var vo:INumbericItemValue in list)
				{
					if (vo.key == value.key)
					{
						vo.concat(temp);
						loop(vo, list, removedList);
						break;
					}
				}
			}
		};
		
		loop(matchItem, items, removed);
		
		return removed;
	}
	
	override public function hasEnoughSpace(value:IItemValue):Boolean
	{
		if (isFull) return false;
		
		var target:INumbericItemValue = value as INumbericItemValue;
		
		var matchItem:INumbericItemValue = findItem(value.key);
		
		var overNum:Number = 0;
		
		//如果有还未叠满的物品		
		if (matchItem)
		{
			overNum = Math.ceil(matchItem.num + target.num) - matchItem.groupCount;
		}
			//如果没有未叠满的物品 或者 没有目前还没有物品		
		else
		{
			overNum = target.num;
		}
		
		if (matchItem && overNum < 0)
		{
			return true;
		}
		else
		{
			var addCount:int = Math.ceil(overNum / target.groupCount);
			
			if (items.length + addCount > currentSpace) return false;
		}
		return true;
	}
	
	override public function getItemNum(itemKey:String, ...args):Number
	{
		return getItemNumByKey(itemKey);
	}
	
	override protected function findItem(itemKey:String):*
	{
		for each (var vo:INumbericItemValue in items)
		{
			if (vo.key == itemKey && !vo.isFull) return vo;
		}
		return null;
	}
}
}



